package com.moose.operator.util;

import java.io.Serializable;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

/**
 * @author taohua
 */

@Slf4j
@Component
public class RedisUtil {

  @Resource
  private RedisTemplate<String, Object> redisTemplate;

  /**
   * 缓存value操作
   *
   * @param k    key
   * @param v    value
   * @param time 时间
   * @param unit 时间单位
   * @return
   */
  public boolean cacheValue(String k, Serializable v, long time, TimeUnit unit) {
    try {
      ValueOperations<String, Object> valueOps = redisTemplate.opsForValue();
      valueOps.set(k, v);
      if (time > 0) {
        redisTemplate.expire(k, time, unit);
      }
      return true;
    } catch (Throwable t) {
      log.error("缓存[{}]失败,key[" + k + ", + v + " + v + " error[" + t + "]");
    }
    return false;
  }

  /**
   * 缓存value操作
   *
   * @param k    key
   * @param v    value
   * @param time 时间
   * @return
   */
  public boolean cacheValue(String k, Serializable v, long time) {
    try {
      return cacheValue(k, v, time, TimeUnit.SECONDS);
    } catch (Throwable t) {
      log.error("缓存[{}]失败,key[" + k + ", + v + " + v + " error[" + t + "]");
    }
    return false;
  }

  /**
   * 缓存value操作
   *
   * @param k key
   * @param v value
   * @return
   */
  public boolean cacheValue(String k, Serializable v) {
    return cacheValue(k, v, -1);
  }

  /**
   * 判断缓存是否存在
   *
   * @param k key
   * @return
   */
  public Boolean hasKey(String k) {
    try {
      return redisTemplate.hasKey(k);
    } catch (Throwable t) {
      log.error("判断缓存存在失败key[" + k + ", error[" + t + "]");
    }
    return Boolean.FALSE;
  }

  /**
   * 递增
   *
   * @param k
   * @param delta 要增加几(大于0)
   * @return
   */
  public long increment(String k, long delta) {
    if (delta < 0) {
      throw new RuntimeException("递增因子必须大于0");
    }
    return redisTemplate.opsForValue().increment(k, delta);
  }

  /**
   * 递减
   *
   * @param k     键
   * @param delta 要减少几(小于0)
   * @return
   */
  public long decrement(String k, long delta) {
    if (delta < 0) {
      throw new RuntimeException("递减因子必须大于0");
    }
    return redisTemplate.opsForValue().increment(k, -delta);
  }

  /**
   * 获取缓存
   *
   * @param k key
   * @return
   */
  public Object getValue(String k) {
    try {
      ValueOperations<String, Object> valueOps = redisTemplate.opsForValue();
      return valueOps.get(k);
    } catch (Throwable t) {
      log.error("获取缓存失败key[" + k + ", error[" + t + "]");
    }
    return null;
  }

  public Object hashGet(String key, Object hashKey) {
    try {
      HashOperations<String, Object, Object> hashOps = redisTemplate.opsForHash();
      return hashOps.get(key, hashKey);
    } catch (Throwable t) {
      log.error("获取缓存失败key[" + key + " hashKey " + hashKey + ", error[" + t + "]");
    }
    return null;
  }

  /**
   * 删除缓存
   *
   * @param k key
   * @return
   */
  public Boolean removeValue(String k) {
    try {
      redisTemplate.expire(k, 0, TimeUnit.SECONDS);
      return Boolean.TRUE;
    } catch (Throwable t) {
      log.error("删除缓存失败key[" + k + ", error[" + t + "]");
    }
    return Boolean.FALSE;
  }

  /**
   * 删除缓存
   *
   * @param k    key
   * @param time time
   * @param unit timeUnit
   * @return
   */
  public Boolean expire(String k, long time, TimeUnit unit) {
    try {
      redisTemplate.expire(k, time, unit);
      return Boolean.TRUE;
    } catch (Throwable t) {
      log.error("设置缓存时间失败key[" + k + ", error[" + t + "]");
    }
    return Boolean.FALSE;
  }
}
